﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using CacheMemory.Models;
using Microsoft.Extensions.Caching.Memory;
using System.Threading;
using Microsoft.Extensions.Primitives;

namespace CacheMemory.Controllers
{
    public class HomeController : Controller
    {
        private IMemoryCache _memoryCache;
        private readonly ILogger<HomeController> _logger;
        int keycount = 0;

        public HomeController(ILogger<HomeController> logger, IMemoryCache memoryCache)
        {
            _logger = logger;
            _memoryCache = memoryCache;
        }

        public IActionResult Index()
        {
            string cacheKey = "key";
            string result;
            if (!_memoryCache.TryGetValue(cacheKey, out result))
            {
                result = $"LineZero{DateTime.Now}";
                _memoryCache.Set(cacheKey, result);
            }
            ViewBag.Cache = result;
            return View();
        }

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }
        public IActionResult SetManyCache(int count)
        {
            for (int i = 0; i < count; i++)
            {
                string cacheKey = $"cache{keycount}:{count}";
                string result;
                if (!_memoryCache.TryGetValue(cacheKey, out result))
                {
                    result = $"{DateTime.Now}:{cacheKey}\r\n";
                    _memoryCache.Set(cacheKey, result);
                    Console.WriteLine($"{cacheKey}-{result}");
                }
            }
            keycount++;
            return Json("批量插入操作成功");
        }
        public IActionResult GetManyCache()
        {

            return Json("批量插入操作成功");
        }
        public IActionResult SetCache(string key, string value)
        {
            string cacheKey = "key:" + key;
            string result;
            if (!_memoryCache.TryGetValue(cacheKey, out result))
            {
                result = $"{DateTime.Now}:{key}-{value}";
                switch (key)
                {
                    case "SetSlidingExpiration":
                        //设置 相对 过期时间2分钟
                        _memoryCache.Set(cacheKey, result + "设置 相对 过期时间2分钟", new MemoryCacheEntryOptions()
                            .SetSlidingExpiration(TimeSpan.FromMinutes(2))); break;
                    case "SetAbsoluteExpiration":
                        //设置 绝对 过期时间2分钟
                        _memoryCache.Set(cacheKey, result + "设置 绝对 过期时间2分钟", new MemoryCacheEntryOptions()
                            .SetAbsoluteExpiration(TimeSpan.FromMinutes(2))); break;
                    case "SetPriority":
                        //缓存优先级 （程序压力大时，会根据优先级自动回收）
                        _memoryCache.Set(cacheKey, result + "缓存优先级 （程序压力大时，会根据优先级自动回收）", new MemoryCacheEntryOptions()
                       .SetPriority(CacheItemPriority.NeverRemove)); break;
                    case "SetAbsoluteExpirationCallBack":
                        //缓存回调 10秒过期会回调
                        _memoryCache.Set(cacheKey, result + "缓存回调 10秒过期会回调", new MemoryCacheEntryOptions()
                            .SetAbsoluteExpiration(TimeSpan.FromSeconds(10))
                            .RegisterPostEvictionCallback((key, value, reason, substate) =>
                            {
                                Console.WriteLine($"键{key}值{value}改变，因为{reason}");
                            })); break;
                    case "AddExpirationToken":
                        //缓存回调 根据Token过期
                        var cts = new CancellationTokenSource();
                        _memoryCache.Set(cacheKey, result, new MemoryCacheEntryOptions()
                            .AddExpirationToken(new CancellationChangeToken(cts.Token))
                            .RegisterPostEvictionCallback((key, value, reason, substate) =>
                            {
                                Console.WriteLine($"键{key}值{value}改变，因为{reason}");
                            }));
                        cts.Cancel(); break;
                    default:
                        break;
                }
            }
            else
            {
                result = $"{key}:缓存已存在";
            }
            return Json(result);
        }
        public IActionResult GetCache(string key)
        {
            string cacheKey = "key:" + key;
            string result;
            if (!_memoryCache.TryGetValue(cacheKey, out result))
            {
                result = $"未获取到缓存";
            }
            return Json($"获取缓存:{result}");
        }
        public IActionResult RemoveCache(string key)
        {
            string cacheKey = "key:" + key;
            string result;
            if (!_memoryCache.TryGetValue(cacheKey, out result))
            {
                result = $"未获取到缓存";
            }
            else
            {
                _memoryCache.Remove(cacheKey);
            }
            return Json($"清除缓存:{result}");
        }
    }
}
